package org.base23.gateway.filter;

import org.base23.gateway.service.JwtService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import reactor.core.publisher.Mono;

@Component
public class JwtAuthenticationGatewayFilterFactory extends
    AbstractGatewayFilterFactory<JwtAuthenticationGatewayFilterFactory.Config> {

  @Autowired
  private JwtService jwtService;

  public JwtAuthenticationGatewayFilterFactory() {
    super(Config.class);
  }

  @Override
  public GatewayFilter apply(Config config) {
    return (exchange, chain) -> {
      ServerHttpRequest request = exchange.getRequest();
      try {
        // 从请求头中获取 Token
        String token = request.getHeaders().getFirst("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
        }
        if (!StringUtils.hasText(token)) {
            throw  new RuntimeException("token is empty!");
        }
        // 校验 Token
        String payload = jwtService.verifyJwt(token, String.class);
        // 提取 payload 并放到 header 中
        ServerHttpRequest modifiedRequest = request.mutate()
            .header("user", payload)
            .build();
        return chain.filter(exchange.mutate().request(modifiedRequest).build());
      } catch (Exception e) {
        // 校验失败，返回 401
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        String jsonResponse = "{\"code\": 401, \"msg\": \"token invalid\", \"data\": null}";
        return response.writeWith(
            Mono.just(response.bufferFactory().wrap(jsonResponse.getBytes())));
      }
    };
  }

  public static class Config {
    // 如果需要配置参数，可以在这里定义
  }
}